package br.ufmg.ubicomp.droidguide.communication;

import java.util.ArrayList;
import java.util.Collection;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import br.ufmg.ubicomp.droidguide.common.EntityProperties;
import br.ufmg.ubicomp.droidguide.communication.CommunicationService;
import br.ufmg.ubicomp.droidguide.eventservice.DroidGuideRemoteService;
import br.ufmg.ubicomp.droidguide.eventservice.DroidGuideServiceParameter;
import br.ufmg.ubicomp.droidguide.eventservice.enums.ParameterType;
import br.ufmg.ubicomp.droidguide.utils.StringUtils;

public class DroidServiceParamCommService extends CommunicationService{

	public Collection<DroidGuideRemoteService> getServiceList() throws Exception
	{
		String url = getServerUrl()+"service/process?operation=list";
		Collection<DroidGuideRemoteService> services = new ArrayList<DroidGuideRemoteService>();		

		NodeList list = processRequest(url);
		
		for (int i = 0; i < list.getLength(); i++) {
			Node entityEntry = list.item(i);
			
			if (entityEntry instanceof Element) {
				Element entityElement = (Element) entityEntry;
				
				if (entityElement.getAttribute("kind").equals("Service")) {
					DroidGuideRemoteService service = getDroidGuideRemoteService(entityElement);
					services.add(service);
				}
			}
		}
		return services;			
	}
	
	private DroidGuideRemoteService getDroidGuideRemoteService(
			Element entityElement) {
		DroidGuideRemoteService service = new DroidGuideRemoteService();
		service.setKey(entityElement.getAttribute("key"));
		
		NodeList properties = entityElement.getChildNodes();
		
		for (int j = 0; j < properties.getLength(); j++) {
			Node propertyEntry = properties.item(j);
			
			if (propertyEntry instanceof Element) {
				Element propertyElement = (Element) propertyEntry;
				
				DroidGuideServiceParameter param = getDroidGuideServiceParameter(propertyElement);
				service.addParameter(param);
			}
		}
		return service;
	}
	
	public DroidGuideRemoteService getService(String serviceKey, String droidGuideUserKey) throws Exception
	{
		String url = getServerUrl()+"service/process?operation=getService&"+
		"service_key="+serviceKey;
		if (!StringUtils.isEmpty(droidGuideUserKey))
		{
			url = url + "&droidGuideUser_key=" + droidGuideUserKey;
		}

		NodeList list = processRequest(url);
		
		DroidGuideRemoteService service = new DroidGuideRemoteService();
		for (int i = 0; i < list.getLength(); i++) {
			Node entityEntry = list.item(i);
			
			if (entityEntry instanceof Element) {
				Element entityElement = (Element) entityEntry;
				
				if (entityElement.getAttribute("kind").equals("Service")) {
					service.setKey(entityElement.getAttribute("key"));
					String dgKey = entityElement.getAttribute("droidGuideUser_key");
					if (!StringUtils.isEmpty(dgKey))
					{
						// TODO armazenar a chave do usuario
					}
					NodeList properties = entityElement.getChildNodes();
					
					for (int j = 0; j < properties.getLength(); j++) {
						Node propertyEntry = properties.item(j);
						
						if (propertyEntry instanceof Element) {
							Element propertyElement = (Element) propertyEntry;
							
							DroidGuideServiceParameter param = getDroidGuideServiceParameter(propertyElement);
							service.addParameter(param);
						}
					}
				}
			}
		}
		return service;	
		
	}

	public EntityProperties saveServiceParameterValue(String serviceKey, String droidGuideUserKey, 
			String serviceParameterKey, String value) throws Exception
	{
		String url = getServerUrl()+"service/process?operation=saveServiceParamValue&"+
		"service_key="+serviceKey+"&service_param_key="+serviceParameterKey+"&droidGuideUser_key="+droidGuideUserKey+"&value="+value;
		
		NodeList list = processRequest(url);
		String key = null;
		EntityProperties entity = new EntityProperties();
		for (int i = 0; i < list.getLength(); i++) {
			Node entityEntry = list.item(i);
			
			if (entityEntry instanceof Element) {
				Element entityElement = (Element) entityEntry;
				entity = getEntityElement(entityEntry);
			}
		}
		return entity;
		
	}
	
	public EntityProperties saveServiceParamValue(String key, String value) throws Exception
	{
		String url = getServerUrl()+"service/process?operation=saveServiceParamValue&"+
		"key="+key+"&value="+value;
		NodeList list = processRequest(url);

		EntityProperties entity = new EntityProperties();
		for (int i = 0; i < list.getLength(); i++) {
			Node entityEntry = list.item(i);
			
			if (entityEntry instanceof Element) {
				entity = getEntityElement(entityEntry);
			}
		}
		return entity;		
	}

	private DroidGuideServiceParameter getDroidGuideServiceParameter(
			Element propertyElement) {
		DroidGuideServiceParameter param = new DroidGuideServiceParameter();
		if (propertyElement.getTagName().equals("param")) {
			Text textNode = (Text) propertyElement
			.getFirstChild();
			String text = null;
			
			if (textNode != null)
			{
				text = textNode.getData().trim();									
			}
			
			String attributeKey = propertyElement.getAttribute("key");
			String attributeName = propertyElement.getAttribute("name");
			String attributeType = propertyElement.getAttribute("type");
			String attributeValueKey = propertyElement.getAttribute("valueKey");
			param.setKey(attributeKey);
			param.setKind("ServiceParameter");
			param.setName(attributeName);
			param.setValue(text);
			param.setType(ParameterType.valueOf(attributeType));
			param.setValueKey(attributeValueKey);
		}
		return param;
	}
}
